/**
 * 钢琴按键跳动可视化器
 */
class PianoKeysVisualizer extends VisualizerInterface {
    constructor(canvas, ctx) {
        super(canvas, ctx);
        this.keys = [];
        this.keyPattern = [0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0]; // 黑白键模式
        this.keyAnimations = [];
    }

    getInfo() {
        return {
            name: 'Piano Keys',
            description: '钢琴黑白按键跳动效果',
            author: 'AudioNN',
            version: '1.0.0',
            category: 'instrument'
        };
    }

    getDefaultSettings() {
        return {
            ...super.getDefaultSettings(),
            whiteKeyColor: '#ffffff',
            blackKeyColor: '#2c2c2c',
            activeWhiteColor: '#4CAF50',
            activeBlackColor: '#FFC107',
            keyCount: 88,
            sensitivity: 1.5,
            decayRate: 0.95,
            glowEffect: true
        };
    }

    getConfigurableParams() {
        return [
            ...super.getConfigurableParams(),
            {
                key: 'keyCount',
                label: '按键数量',
                type: 'range',
                min: 24,
                max: 88,
                step: 1,
                default: 88
            },
            {
                key: 'whiteKeyColor',
                label: '白键颜色',
                type: 'color',
                default: '#ffffff'
            },
            {
                key: 'blackKeyColor',
                label: '黑键颜色',
                type: 'color',
                default: '#2c2c2c'
            },
            {
                key: 'glowEffect',
                label: '发光效果',
                type: 'boolean',
                default: true
            }
        ];
    }

    init(config = {}) {
        super.init(config);
        this.initializeKeys();
        return this;
    }

    initializeKeys() {
        this.keys = [];
        this.keyAnimations = [];
        
        const width = this.canvas.width / window.devicePixelRatio;
        const height = this.canvas.height / window.devicePixelRatio;
        
        // 计算白键和黑键的数量
        const whiteKeyCount = Math.ceil(this.settings.keyCount * 7 / 12);
        const whiteKeyWidth = width / whiteKeyCount;
        const blackKeyWidth = whiteKeyWidth * 0.6;
        const whiteKeyHeight = height * 0.8;
        const blackKeyHeight = height * 0.5;
        
        let whiteKeyIndex = 0;
        
        // 创建钢琴键布局
        for (let i = 0; i < this.settings.keyCount; i++) {
            const octave = Math.floor(i / 12);
            const keyInOctave = i % 12;
            const isBlack = this.keyPattern[keyInOctave] === 1;
            
            if (!isBlack) {
                // 白键
                this.keys.push({
                    type: 'white',
                    x: whiteKeyIndex * whiteKeyWidth,
                    y: height - whiteKeyHeight,
                    width: whiteKeyWidth - 2,
                    height: whiteKeyHeight,
                    frequencyIndex: i,
                    note: this.getNoteFromIndex(i)
                });
                whiteKeyIndex++;
            }
            
            this.keyAnimations.push({
                intensity: 0,
                velocity: 0,
                lastTrigger: 0
            });
        }
        
        // 添加黑键（在白键之后绘制，覆盖在上面）
        whiteKeyIndex = 0;
        for (let i = 0; i < this.settings.keyCount; i++) {
            const keyInOctave = i % 12;
            const isBlack = this.keyPattern[keyInOctave] === 1;
            
            if (isBlack) {
                // 黑键位于两个白键之间
                const whiteKeyX = (whiteKeyIndex - 0.5) * whiteKeyWidth;
                this.keys.push({
                    type: 'black',
                    x: whiteKeyX - blackKeyWidth / 2,
                    y: height - whiteKeyHeight,
                    width: blackKeyWidth,
                    height: blackKeyHeight,
                    frequencyIndex: i,
                    note: this.getNoteFromIndex(i)
                });
            } else {
                whiteKeyIndex++;
            }
        }
        
        // 按绘制顺序排序（白键在前，黑键在后）
        this.keys.sort((a, b) => {
            if (a.type === 'white' && b.type === 'black') return -1;
            if (a.type === 'black' && b.type === 'white') return 1;
            return 0;
        });
    }

    getNoteFromIndex(index) {
        const notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
        const octave = Math.floor(index / 12);
        const noteIndex = index % 12;
        return `${notes[noteIndex]}${octave}`;
    }

    render(frequencyData, cachedData = null, currentTime = 0) {
        this.clearCanvas();
        
        const width = this.canvas.width / window.devicePixelRatio;
        const height = this.canvas.height / window.devicePixelRatio;
        
        // 更新按键动画
        this.updateKeyAnimations(frequencyData, cachedData);
        
        // 绘制钢琴键盘背景
        this.drawPianoBackground(width, height);
        
        // 绘制按键
        this.keys.forEach((key, index) => {
            this.drawKey(key, this.keyAnimations[key.frequencyIndex]);
        });
        
        // 绘制音符标签（可选）
        if (this.settings.showNoteLabels) {
            this.drawNoteLabels();
        }
    }

    updateKeyAnimations(frequencyData, cachedData) {
        const dataToUse = cachedData || frequencyData;
        if (!dataToUse) return;
        
        const freqPerKey = dataToUse.length / this.settings.keyCount;
        
        for (let i = 0; i < this.settings.keyCount; i++) {
            const animation = this.keyAnimations[i];
            
            // 获取对应频率范围的平均值
            const startFreq = Math.floor(i * freqPerKey);
            const endFreq = Math.floor((i + 1) * freqPerKey);
            let avgValue = 0;
            
            for (let j = startFreq; j < endFreq && j < dataToUse.length; j++) {
                avgValue += dataToUse[j];
            }
            avgValue /= (endFreq - startFreq);
            
            // 应用灵敏度和阈值
            const normalizedValue = (avgValue / 255) * this.settings.sensitivity;
            
            // 检测音符触发
            if (normalizedValue > 0.3 && Date.now() - animation.lastTrigger > 50) {
                animation.velocity = normalizedValue;
                animation.lastTrigger = Date.now();
            }
            
            // 更新强度和衰减
            animation.intensity = Math.max(0, animation.intensity * this.settings.decayRate);
            if (animation.velocity > 0) {
                animation.intensity = Math.min(1, animation.intensity + animation.velocity * 0.1);
                animation.velocity *= 0.9;
            }
        }
    }

    drawPianoBackground(width, height) {
        // 绘制钢琴外框
        this.ctx.fillStyle = '#1a1a1a';
        this.ctx.fillRect(0, 0, width, height);
        
        // 绘制钢琴底座
        const gradient = this.ctx.createLinearGradient(0, height * 0.8, 0, height);
        gradient.addColorStop(0, '#333333');
        gradient.addColorStop(1, '#111111');
        this.ctx.fillStyle = gradient;
        this.ctx.fillRect(0, height * 0.8, width, height * 0.2);
    }

    drawKey(key, animation) {
        const { x, y, width, height, type } = key;
        const intensity = animation.intensity;
        
        // 计算颜色
        let fillColor, strokeColor;
        
        if (type === 'white') {
            if (intensity > 0) {
                const r = Math.floor(255 * (1 - intensity) + parseInt(this.settings.activeWhiteColor.slice(1, 3), 16) * intensity);
                const g = Math.floor(255 * (1 - intensity) + parseInt(this.settings.activeWhiteColor.slice(3, 5), 16) * intensity);
                const b = Math.floor(255 * (1 - intensity) + parseInt(this.settings.activeWhiteColor.slice(5, 7), 16) * intensity);
                fillColor = `rgb(${r}, ${g}, ${b})`;
            } else {
                fillColor = this.settings.whiteKeyColor;
            }
            strokeColor = '#cccccc';
        } else {
            if (intensity > 0) {
                const r = Math.floor(44 * (1 - intensity) + parseInt(this.settings.activeBlackColor.slice(1, 3), 16) * intensity);
                const g = Math.floor(44 * (1 - intensity) + parseInt(this.settings.activeBlackColor.slice(3, 5), 16) * intensity);
                const b = Math.floor(44 * (1 - intensity) + parseInt(this.settings.activeBlackColor.slice(5, 7), 16) * intensity);
                fillColor = `rgb(${r}, ${g}, ${b})`;
            } else {
                fillColor = this.settings.blackKeyColor;
            }
            strokeColor = '#000000';
        }
        
        // 绘制按键阴影
        this.ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
        this.ctx.fillRect(x + 2, y + 2, width, height);
        
        // 绘制按键主体
        this.ctx.fillStyle = fillColor;
        this.ctx.fillRect(x, y, width, height);
        
        // 绘制按键边框
        this.ctx.strokeStyle = strokeColor;
        this.ctx.lineWidth = 1;
        this.ctx.strokeRect(x, y, width, height);
        
        // 绘制按键按下效果
        if (intensity > 0.1) {
            const pressDepth = intensity * 5;
            this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
            this.ctx.fillRect(x, y + height - pressDepth, width, pressDepth);
        }
        
        // 绘制发光效果
        if (this.settings.glowEffect && intensity > 0.2) {
            this.ctx.shadowColor = fillColor;
            this.ctx.shadowBlur = intensity * 20;
            this.ctx.fillStyle = fillColor;
            this.ctx.fillRect(x, y, width, height);
            this.ctx.shadowBlur = 0;
        }
        
        // 绘制强度指示器
        if (intensity > 0.1) {
            const indicatorHeight = intensity * height * 0.8;
            const indicatorY = y + height - indicatorHeight;
            
            const gradient = this.ctx.createLinearGradient(x, indicatorY, x, y + height);
            gradient.addColorStop(0, `rgba(255, 255, 255, ${intensity * 0.5})`);
            gradient.addColorStop(1, `rgba(255, 255, 255, 0)`);
            
            this.ctx.fillStyle = gradient;
            this.ctx.fillRect(x + width * 0.1, indicatorY, width * 0.8, indicatorHeight);
        }
    }

    drawNoteLabels() {
        this.ctx.fillStyle = '#666666';
        this.ctx.font = '10px Arial';
        this.ctx.textAlign = 'center';
        
        this.keys.forEach(key => {
            if (key.type === 'white' && key.frequencyIndex % 12 === 0) {
                this.ctx.fillText(
                    key.note,
                    key.x + key.width / 2,
                    key.y + key.height - 10
                );
            }
        });
    }

    resize(width, height) {
        this.initializeKeys();
    }
}

// 注册可视化器到全局注册表
if (typeof window !== 'undefined') {
    if (!window.visualizerRegistrations) {
        window.visualizerRegistrations = [];
    }
    window.visualizerRegistrations.push({
        id: 'piano-keys',
        class: PianoKeysVisualizer
    });
}

// 导出
window.PianoKeysVisualizer = PianoKeysVisualizer;
